//The MIT License
//
//Copyright (c) 2009 nodchip
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
package tv.dyndns.kishibe.client;

import java.util.List;
import java.util.Map;
import java.util.Set;

import tv.dyndns.kishibe.client.game.GameMode;
import tv.dyndns.kishibe.client.packet.PacketBbsResponse;
import tv.dyndns.kishibe.client.packet.PacketBbsThread;
import tv.dyndns.kishibe.client.packet.PacketChatData;
import tv.dyndns.kishibe.client.packet.PacketGameStatus;
import tv.dyndns.kishibe.client.packet.PacketLinkData;
import tv.dyndns.kishibe.client.packet.PacketMatchingPlayer;
import tv.dyndns.kishibe.client.packet.PacketProblemCreationLog;
import tv.dyndns.kishibe.client.packet.PacketProblemData;
import tv.dyndns.kishibe.client.packet.PacketRankingData;
import tv.dyndns.kishibe.client.packet.PacketRatingDistribution;
import tv.dyndns.kishibe.client.packet.PacketRegistrationData;
import tv.dyndns.kishibe.client.packet.PacketResult;
import tv.dyndns.kishibe.client.packet.PacketRoomKey;
import tv.dyndns.kishibe.client.packet.PacketServerStatus;
import tv.dyndns.kishibe.client.packet.PacketUserData;
import tv.dyndns.kishibe.client.packet.PacketWrongAnswer;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.ServiceDefTarget;

public interface Service extends RemoteService {
	public static class Util {
		public static ServiceAsync getInstance() {
			ServiceAsync instance = (ServiceAsync) GWT.create(Service.class);
			ServiceDefTarget target = (ServiceDefTarget) instance;
			target.setServiceEntryPoint(GWT.getModuleBaseURL() + SERVICE_URI);
			return instance;
		}
	}

	public static final String SERVICE_URI = "/service";

	public static final AsyncCallback<Object> NULL_CALLBACK = new AsyncCallback<Object>() {
		public void onFailure(Throwable caught) {
		}

		public void onSuccess(Object result) {
		}
	};

	public void addIgnoreUserCode(int userCode, int targetUserCode);

	public void addLinkData(PacketLinkData linkData);

	public void addProblemIdsToReport(int userCode, int[] problemIds);

	public void addRatingHistory(int userCode, int rating);

	public void buildBbsThread(PacketBbsThread thread, PacketBbsResponse response);

	// 問題評価文をクリアする
	public void clearProblemFeedback(int problemId);

	public void clearProblemIDFromReport(int userCode);

	public Set<String> getAvailableChalactersForHandwriting();

	public PacketBbsResponse[] getBbsResponses(int threadId, int count);

	public PacketBbsThread[] getBbsThread(int start, int count);

	// イベント部屋情報を取得する
	public List<PacketRoomKey> getEventRooms();

	// ゲームの進行状態を取得する
	public PacketGameStatus getGameStatus(int sessionId, int playerListId);

	public PacketLinkData[] getLinkDatas(int start, int count);

	public PacketUserData[] getLoginUsers();

	// マッチング中の相手のデータを取得する
	public PacketMatchingPlayer[] getMachingPlayer(int sessionId);

	public int getNewUserCode();

	public int getNumberOfBbsThreads();

	public int getNumberOfLinkDatas();

	// PlayerHistoryを取得する
	public String[] getPlayerHistory();

	// 他のプレイヤーの名前を取得する
	public String[] getPlayerNameList(int sessionId);

	public int[][] getPrefectureRanking();

	public PacketProblemCreationLog[] getProblemCreationLog(int problemId);

	public PacketProblemData[] getProblemData(int sessionId);

	// 問題評価文を取得する
	public List<String> getProblemFeedback(int problemId);

	// 問題を取得する
	public PacketProblemData[] getProblemList(List<Integer> problemIds);

	public PacketRankingData[][] getRankingData();

	public PacketRatingDistribution getRatingDistribution();

	public int[] getRatingHistory(int userCode);

	// 結果表示
	// 最終結果を取得する
	public PacketResult[] getResult(int sessionId);

	// サーバーの状態を取得する
	public PacketServerStatus getServerStatus(boolean isFirst, int userCode);

	public int getSessionTransition(int sessionId);

	public int[][] getStatisticsOfAccuracyRate();

	// 問題統計情報を取得する
	public int[][] getStatisticsOfProblemCount();

	public Map<String, PacketRankingData[]> getThemeModeRanking();

	public String[] getThemeModeThemes();

	public PacketProblemData[] getUserProblemReport(int userCode);

	public PacketWrongAnswer[] getWrongAnswers(int problemId);

	public boolean isLimitedUser(int userCode);

	public PacketUserData loadUserData(int userCode);

	// チャットからメッセージを受信する
	public PacketChatData[] receiveMessageFromChat(int nextArrayIndex);

	// 手書き文字の識別を行う
	public String[] recognizeHandwriting(double[][][] strokes);

	// プレイヤー情報を登録する
	public PacketRegistrationData register(String name, int genre, int type, String greeting, GameMode gameMode, String roomName, String theme, String imageFileName, int classLevel, int difficultSelect, int rating, int userCode, boolean newProblem, boolean publicEvent);

	public void removeIgnoreUserCode(int userCode, int targetUserCode);

	public void removeLinkData(int id);

	// 誤解答を削除する
	public void removePlayerAnswers(int problemID);

	public void removeProblemIDFromReport(int userCode, int problemId);

	public void reportLogin(int userCode);

	// 強制的にゲームをスタートさせる
	public int requestSkip(int sessionId, int playerListId);

	public void saveUserData(PacketUserData userData);

	// 問題の検索を行う
	public PacketProblemData[] searchProblem(String query, String creater, int genre, int type, int randomFlag);

	// 類似問題を検索する
	public PacketProblemData[] searchSimilarProblem(String query);

	// ゲーム
	// 自分の解答を送る
	public Boolean sendAnswer(int sessionId, int playerListId, String answer);

	// チャットにメッセージを送信する
	public void sendMessageToChat(PacketChatData chatData);

	public void updateLinkData(PacketLinkData linkData);

	// 問題を投稿する
	public int uploadProblem(PacketProblemData problemData, int userCode);

	// 投票を行う
	public void voteToProblem(int userCode, int problemId, boolean good, String feedback);

	// ゲーム開始待機
	public int waitForGame(int sessionId);

	// マッチング 他の対戦者の参加を待つ
	public int waitForMatching(int sessionId, int playerListId);

	public void writeToBbs(PacketBbsResponse response, boolean age);

	public Map<String, List<String>> getThemeModeQuery();

	public void addThemeModeQuery(String theme, String query);

	public void removeThemeModeQuery(String theme, String query);

	public boolean isThemeModeEditor(int userCode);

	public void applyThemeModeEditor(int userCode, String text);

	public void acceptThemeModeEditor(int userCode);

	public void rejectThemeModeEditor(int userCode);

	public Map<Integer, Integer> getThemeModeEditors();

	public boolean isApplyingThemeModeEditor(int userCode);
}
